﻿#include "stdafx.h"//由W意波(LuoJun)编写，狂沙十万里提供修改意见
#ifdef LK_TIME_
namespace LK
{
	//ptr<Time>
	StaticProperty<PTime> Time::Now = StaticProperty<PTime>(Time::GetLocal, Time::SetLocal);
	//获取当前类名

	const double Time::EveryMicrosecond = 1e-6;
	const double Time::EveryMillisecond = 1e-3;
	const double Time::EverySecond = 1;
	const double Time::EveryMinute = 60;
	const double Time::EveryHour = 3600;
	const double Time::EveryDay = 24 * 3600;
	const double Time::EveryWeek = 7* 24 * 3600;

	double Time::GetDays(double year, unsigned int month, unsigned int day)
	{
		year = floor(year);
		static unsigned short rm[13] = { 0,0,31,60,91,121,152,182,213,244,274,305,335 };
		static unsigned short m[13] = { 0,0,31,59,90,120,151,181,212,243,273,304,334 };
		if (fmod(year, 400) == 0 || (((s64)year) % 4 == 0 && ((s64)year) % 100 != 0))//闰年
		{
			return rm[month] + day + year * 365 - 366 + (year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400;
		}
		return m[month] + day + year * 365 - 366 + (year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400;
	}
	unsigned int Time::GetMonthByDaysInYear(double year, unsigned int& days)
	{
		year = floor(year);
		unsigned int day = days;
		if (fmod(year, 400) == 0 || ((u64)year % 4 == 0 && (u64)year % 100 != 0))//闰年
		{
			static unsigned char d[366] =
			{ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
			1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,
			1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
			1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,
			1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
			1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,
			1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
			1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
			1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,
			1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
			1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,
			1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 };
			static unsigned char m[366] =
			{ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
			2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
			3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
			4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
			5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
			6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
			7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
			8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
			9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
			10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
			11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
			12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12 };
			days = d[day];
			return m[day];
		}
		static unsigned char Dd[365] =
		{ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
		1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,
		1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
		1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,
		1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
		1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,
		1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
		1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
		1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,
		1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
		1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,
		1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 };
		static unsigned char Mm[365] =
		{ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
		2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
		3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
		4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
		5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
		6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
		9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
		10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
		11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
		12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12 };
		days = Dd[day];
		return Mm[day];
	}
	double Time::GetLocalSeconds()//获取当前的本地时间
	{
#ifdef _WINDOWS
		static volatile int tryCounter = 0;//0尝试使用CPU计数器，1使用CPU计数器，-1采用GetLocalTime
		static volatile short lastday = -1;//用以进行持续运行时的清零操作
		static volatile double daymns = 0;
		static volatile double mns = 0;
		static LARGE_INTEGER frequency = { 0 };//CPU频率
		static LARGE_INTEGER last = { 0 };
		if (!tryCounter){//首次计时，初始化daymns
			if (!QueryPerformanceFrequency(&frequency)) { tryCounter = -1; return GetLocalSeconds(); }//获取时钟频率,失败则禁用
			if (!QueryPerformanceCounter(&last)) { tryCounter = -1; return GetLocalSeconds(); }//计数器
			::SYSTEMTIME t;
			::GetLocalTime(&t);
			daymns = GetDays(t.wYear, t.wMonth, t.wDay)*EveryDay;
			mns = t.wMilliseconds*EveryMillisecond//毫秒
				+ t.wSecond//秒
				+ t.wMinute*EveryMinute//分
				+ t.wHour*EveryHour//时
				+ daymns;
			lastday = t.wDay;
			tryCounter = 1;//启用CPU时间计时
			return mns;
		}
		if (tryCounter<0)//无法采CPU时钟，直接用WindowsAPI
		{
			::SYSTEMTIME t;
			::GetLocalTime(&t);
			if (t.wDay != lastday)
			{
				daymns = GetDays(t.wYear, t.wMonth, t.wDay)*EveryDay;
				lastday = t.wDay;
			}
			return t.wMilliseconds*EveryMillisecond//毫秒
				+ t.wSecond*EverySecond//秒
				+ t.wMinute*EveryMinute//分
				+ t.wHour*EveryHour//时
				+ daymns;
		}
		long long i = CpuCounterReference().QuadPart;
		if ((i -= last.QuadPart)>(1000*24*3600*10000000ll))tryCounter = 0;//1000天重新采一次mns，防止 QuadPart - last.QuadPart过大超出表示范围
		return double(i) / frequency.QuadPart + mns;
		//#else
		//#ifdef _LINUX

#else
		time_t rawtime;
		struct tm * timeinfo;
		::time(&rawtime);
		timeinfo = localtime(&rawtime);
		return GetDays(timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, timeinfo->tm_mday)*EveryDay
			+ timeinfo->tm_hour*EveryHour
			+ timeinfo->tm_min*EveryMinute
			+ timeinfo->tm_sec
			+ (clock() / (double)CLOCKS_PER_SEC - (long long)(clock() / (double)CLOCKS_PER_SEC);
		//#endif
#endif
	}
	void Time::SetLocal(const PTime& now)//设置当前的本地时间
	{
#ifdef _WINDOWS
		::SYSTEMTIME t = Time(*now.Check());
		::SetLocalTime(&t);
#else

#endif
	}
	ptr<Time> Time::GetLocal() { return GetLocalSeconds(); }

	Time::Time()//构造,并置零
		:time(0)
	{}
	Time::Time(double t)//使用一个数值来初始化
		: time(t){}
#ifdef _WINDOWS
	Time::Time(const ::SYSTEMTIME& t)//使用一个系统时间来初始化
		: time(t.wMilliseconds*EveryMillisecond//毫秒
			+ t.wSecond*EverySecond//秒
			+ t.wMinute*EveryMinute//分
			+ t.wHour*EveryHour//时
			+ GetDays(t.wYear, t.wMonth, t.wDay)*EveryDay)
	{}
#endif
	Time::Time(const ::tm& t)//使用一个系统时间来初始化
		:time(t.tm_sec*EverySecond//秒
			+ t.tm_min*EveryMinute//分
			+ t.tm_hour*EveryHour//时
			+ GetDays(t.tm_year, t.tm_mon, t.tm_mday)*EveryDay){}
	Time::Time(const ptr<String>&tmpstr)
	{
		//static ptr<String> monthString[12]={L"january",L"february",L"march",L"april",L"may",L"june",L"july",L"august",L"september",L"october",L"november",L"december"};
		//static ptr<String> monthShortString[12]={L"jan",L"feb",L"mar",L"apr",L"may",L"jun",L"jul",L"aug",L"sept",L"oct",L"nov",L"dec"};
		//static LK::Collection::DefaultArray<ptr<String>> months(12,monthString,String::Reference);
		//static LK::Collection::DefaultArray<ptr<String>> monthsShort(12,monthShortString,String::Reference);
		static LPCWSTR splitWchars = L" t";
		static PWCharArray  splitWchs = new Collection::ReferenceArray<WCHAR>(2, (LPWSTR)splitWchars);
		//默认时间0//获取当前时间
		time = 0;// GetLocal();
		//转换为小写
		ptr<String> str = tmpstr.ToLower();
		//字符串初步分割
		PStringArray  strs = str.Split(splitWchs);
		//是否已记录过
		bool hasymd = false;
		bool hashms = false;
		//分段检测
		for (index_t i = 0; i < strs->size(); ++i)
		{
			static ptr<String> strContains1 = L"-";
			static ptr<String> strContains2 = L"/";
			static ptr<String> strContains3 = L":";
			static ptr<String> strContains4 = L"年";
			static ptr<String> strContains5 = L"月";
			static ptr<String> strContains6 = L"日";
			if (!hasymd && (strs[i].Contains(strContains1) || strs[i].Contains(strContains2)))
			{
				PStringArray  ymd = strs[i].GetNumbers();
				if (ymd->size() == 3)
				{
					SetYear((int)ymd[0].ToUInt64());//年
					SetMonth((int)ymd[1].ToUInt64());//月
					SetDay((int)ymd[2].ToUInt64());//日
					hasymd = true;//已记录年月日
					if (hashms)break;
				}
			}
			else if (!hashms&&strs[i].Contains(strContains3))
			{
				PStringArray  hms = strs[i].GetNumbers();
				static ptr<String> strContains7 = L"pm";
				bool afternoon = strs[i].Contains(strContains7);
				switch (hms->size())
				{
				case 4:time = (time / EverySecond)*EverySecond + hms[3].PadRight(7, L'0').ToUInt64();
				case 3:SetSecond((int)hms[2].ToUInt64());
				case 2:SetMinute((int)hms[1].ToUInt64());
					if (afternoon)SetHour(12 + (int)hms[0].ToUInt64());
					else SetHour((int)hms[0].ToUInt64());
				default:hashms = true;//已记录时分秒
				}
				if (hasymd)break;
			}
			else if (!hasymd && (strs[i].Contains(strContains4) || strs[i].Contains(strContains5) || strs[i].Contains(strContains6)))
			{
				index_t tmp = strs[i].IndexOf(strContains4);
				if (tmp > 0)SetYear((int)strs[i].Substring(0, tmp).GetNumbers()->LastElement().ToUInt64());
				tmp = strs[i].IndexOf(strContains5);
				if (tmp > 0)SetMonth((int)strs[i].Substring(0, tmp).GetNumbers()->LastElement().ToUInt64());
				tmp = strs[i].IndexOf(strContains6);
				if (tmp > 0)SetDay((int)strs[i].Substring(0, tmp).GetNumbers()->LastElement().ToUInt64());
				hasymd = true;
				if (hashms)break;
			}
		}
	}

	Time& Time::operator=(const Time& t)//赋值运算
	{
		time = t.time;
		return *this;
	}
	Time& Time::operator=(double t)
	{
		time = t;
		return *this;
	}



	//同时获取年份和年天数
	double Time::GetYearAndDaysInYear(unsigned int* pday)const
	{
		double year = floor(time / EveryDay);
		long long days = (s64)fmod(year, 146097);//获取400年分天数，按400年一个周期一共365*400+97=146097天计算
		year = floor(year/ 146097) * 400;//年初算
		if (days >= 146097 - 366) { if (pday)*pday = (unsigned int)(days - (146097 - 366)); return (year + 400); }
		year += days / 36524 * 100;//获取100年分天数，按100年一个周期一共365*100+24=36524天计算
		days %= 36524; if (days >= 36524 - 365) { if (pday)*pday = (unsigned int)(days - (36524 - 365)); return (year + 100); }
		year += days / 1461 * 4;//获取4年分天数，按4年一个周期一共365*4+1=1461天计算
		days %= 1461; if (days >= 1461 - 366) { if (pday)*pday = (unsigned int)(days - (1461 - 366)); return (year + 4); }
		if (pday)*pday = (unsigned int)(days % 365); return (year + 1 + days / 365);
	}
	double Time::GetYear()const
	{
		return GetYearAndDaysInYear(0);
	}
	unsigned int Time::GetMonth()const
	{
		unsigned int days;
		double year = GetYearAndDaysInYear(&days);
		return GetMonthByDaysInYear(year, days);
	}
	unsigned int Time::GetDay()const
	{
		unsigned int days;
		double year = GetYearAndDaysInYear(&days);
		GetMonthByDaysInYear(year, days);
		return days;
	}
	unsigned int Time::GetDayOfWeek()const//取星期几，1天的漂移
	{
		return (ui32)(fmod(time,EveryWeek) / EveryDay + 1) % 7;
	}
	unsigned int Time::GetHour()const//取时
	{
		return (unsigned int)((ui32)fmod((time > 0 ? time : -time) , EveryDay) / EveryHour);
	}
	unsigned int Time::GetMinute()const//取分
	{
		return (unsigned int)(fmod((time > 0 ? time : -time) , EveryHour) / EveryMinute);
	}
	unsigned int Time::GetSecond()const//取秒
	{
		return (unsigned int)(fmod((time > 0 ? time : -time) , EveryMinute) / EverySecond);
	}
	unsigned int Time::GetMillisecond()const//取毫秒
	{
		return (unsigned int)(fmod((time > 0 ? time : -time) , EverySecond) / EveryMillisecond);
	}
	unsigned int Time::GetMicrosecond()const//取微秒
	{
		return (unsigned int)(fmod((time > 0 ? time : -time) , EveryMillisecond) / EveryMicrosecond);
	}
	void Time::SetYear(double year)//设置年
	{
		double ticks = fmod(time,EveryDay);
		unsigned int days;
		GetYearAndDaysInYear(&days);
		unsigned int month = GetMonthByDaysInYear(year, days);
		time = ticks + EveryDay* GetDays(year, month, days);
	}
	void Time::SetMonth(unsigned int month)//设置月
	{
		double ticks = fmod(time, EveryDay);
		unsigned int days;
		double year = GetYearAndDaysInYear(&days);
		GetMonthByDaysInYear(year, days);
		time = ticks + EveryDay* GetDays(year, month, days);
	}
	void Time::SetDay(unsigned int day)//设置日
	{
		time += (day - GetDay())*EveryDay;
	}
	void Time::SetHour(unsigned int hour)//设置时
	{
		time = time / EveryDay * EveryDay + fmod(time , EveryHour) + hour * EveryHour;
	}
	void Time::SetMinute(unsigned int minute)//设置分
	{
		time = time / EveryHour * EveryHour + fmod(time , EveryMinute) + minute * EveryMinute;
	}
	void Time::SetSecond(unsigned int second)//设置秒
	{
		time = time / EveryMinute * EveryMinute + fmod(time , EverySecond) + second * EverySecond;
	}
	void Time::SetMillisecond(unsigned int millisecond)//设置毫秒
	{
		time = time / EverySecond * EverySecond + fmod(time , EveryMillisecond) + millisecond * EveryMillisecond;
	}
	void Time::SetMicrosecond(unsigned int microsecond)//设置微秒
	{
		time = time / EveryMillisecond * EveryMillisecond + fmod(time , EveryMicrosecond) + microsecond * EveryMicrosecond;
	}

	double Time::GetDays()const//获取公园至今已过天数
	{
		return floor(time / EveryDay);
	}
	double  Time::GetHours()const//获取公园元年至该时间已过小时数(可能为负)
	{
		return floor(time / EveryHour);
	}
	double Time::GetMinutes()const//获取公园元年至该时间已过分数(可能为负)
	{
		return floor(time / EveryMinute);
	}
	double Time::GetSeconds()const//获取公园元年至该时间已过秒数(可能为负)
	{
		return floor( time / EverySecond);
	}
	double Time::GetMilliseconds()const//获取公园元年至该时间已过毫秒数(可能为负)
	{
		return floor(time / EveryMillisecond);
	}
	double Time::GetMicroseconds()const//获取公园元年至该时间已过微秒数(可能为负)
	{
		return floor(time / EveryMicrosecond);
	}

	Time::operator double()const//转换为以100ns为单位的整数
	{
		return time;
	}
#ifdef _WINDOWS
	Time::operator ::SYSTEMTIME()const//转换为WindowsAPI中的日期
	{
		SYSTEMTIME t;
		t.wMilliseconds = (unsigned short)GetMillisecond();//毫秒
		t.wSecond = (unsigned short)GetSecond();//秒
		t.wMinute = (unsigned short)GetMinute();//分
		t.wHour = (unsigned short)GetHour();//小时
		t.wDayOfWeek = (unsigned short)GetDayOfWeek();//星期x

		unsigned int days;
		t.wYear = (unsigned short)GetYearAndDaysInYear(&days);
		t.wMonth = (unsigned short)GetMonthByDaysInYear(t.wYear, days);
		t.wDay = (unsigned short)days;
		return t;
	}
#endif
	Time::operator ::tm()const//转换为WindowsAPI中的日期
	{
		::tm t;
		t.tm_sec = (unsigned short)GetSecond();//秒
		t.tm_min = (unsigned short)GetMinute();//分
		t.tm_hour = (unsigned short)GetHour();//小时
		t.tm_wday = (unsigned short)GetDayOfWeek();//星期x

		unsigned int days;
		t.tm_year = (unsigned short)GetYearAndDaysInYear(&days);
		t.tm_yday = days;
		t.tm_mon = (unsigned short)GetMonthByDaysInYear(t.tm_year, days);
		t.tm_mday = days;
		return t;
	}
	void Time::Wait(const Time& t)
	{
		if (time == 0)time = GetLocalSeconds();
		*this += t;
		if (t < EveryMillisecond)
		{
			if (t < EveryMicrosecond)return;
			Sleep(0);
			return;
		}
		Time now = GetLocalSeconds();
		if (*this <= now)return;
		Sleep(DWORD((*this - now) / EveryMillisecond));
	}
	void Time::AddTypeInfo()
	{
#ifdef LK_REFLECTION_
		using namespace Reflection;
		using namespace Functional;
		//获取全局命名空间
		PNamespaceNode space = GetGlobleLibrary().GetGlobleNamespaceRef().FindOrAddNamespace(L"LK");
		//查找或添加ptr<Time>类型节点
		PTypeNode node = space.FindOrAddTypeNode(L"Time", Type::Make<ptr<Time>>());
		//添加成员函数
		typedef fref<PString(Time::*)()const, &Time::ToString> fToString;
		node.AddFunction(L"ToString", PFunObjs(( fToString::T)&fToString::operator()));
		//node.AddFunction(L"ToString", PFunObjs((ptr<String>(ptr<Time>::*)()const)&ptr<Time>::ToString));
		//设置继承关系
		node.AddBaseType(Type::Make<ptr<Object>>());
#endif
	}

	ptr<String> Time::ToString()const
	{
		LPWSTR tmpStr = new WCHAR[80];// = L"+00000000day 00:00:00.0000000";
		LPWSTR pstr = tmpStr;
		double num = time>0 ? GetDays() : -GetDays();
		if (time < 0) *(tmpStr++) = L'-';
		if (num != 0)
		{
			if (num < 1e16)
				tmpStr+=String::WriteUNum((u64)num, tmpStr, 1);
			else 
				tmpStr += String::WriteFloatE(num, tmpStr, 52);
			*(tmpStr++) = L'D';
			*(tmpStr++) = L'a';
			*(tmpStr++) = L'y';
			*(tmpStr++) = L's';
			*(tmpStr++) = ' ';
		}
		num = GetHour();
		*(tmpStr++) = (WCHAR)(num / 10) + L'0';
		*(tmpStr++) = (u32)num % 10 + L'0';
		*(tmpStr++) = L':';
		num = GetMinute();
		*(tmpStr++) = (WCHAR)(num / 10) + L'0';
		*(tmpStr++) = (u32)num % 10 + L'0';
		*(tmpStr++) = L':';
		num = GetSecond();
		*(tmpStr++) = (WCHAR)(num / 10) + L'0';
		*(tmpStr++) = (u32)num % 10 + L'0';
		num = (time < 0 ? -time : time)* 1000000;
		*(tmpStr++) = L'.';
		*(tmpStr++) = (WCHAR)(((u32)num % 10000000) / 1000000) + L'0';
		*(tmpStr++) = (WCHAR)(((u32)num % 1000000) / 100000) + L'0';
		*(tmpStr++) = (WCHAR)(((u32)num % 100000) / 10000) + L'0';
		*(tmpStr++) = (WCHAR)(((u32)num % 10000) / 1000) + L'0';
		*(tmpStr++) = (WCHAR)(((u32)num % 1000) / 100) + L'0';
		*(tmpStr++) = (WCHAR)(((u32)num % 100) / 10) + L'0';
		*(tmpStr++) = (WCHAR)((u32)num % 10) + L'0';
		*tmpStr = 0;
		return new String(int(tmpStr - pstr), pstr, NULL);
		//ptr<String> str;
		//if(GetDays())str = ptr<String>(GetDays(),L"%dd ")+ptr<String>(GetHour()).PadLeft(2,L'0');
		//else str = ptr<String>(GetHours());
		//str+=ptr<String>(L":")+ptr<String>(GetMinute()).PadLeft(2,L'0');
		//str+=ptr<String>(L":")+ptr<String>(GetSecond()).PadLeft(2,L'0');
		//return str+ptr<String>(L".")+ptr<String>(time%EverySecond).PadLeft(7,L'0');
	}
	ptr<String> Time::ToString(const ptr<String>&str)const
	{
		//static LPCWSTR monthString[12]={L"January",L"February",L"March",L"April",L"May",L"June",L"July",L"August",L"September",L"October",L"November",L"December"};
		//static LPCWSTR monthShortString[12]={L"Jan",L"Feb",L"Mar",L"Apr",L"May",L"Jun",L"Jul",L"Aug",L"Sept",L"Oct",L"Nov",L"Dec"};
		static LPCWSTR weekString[7] = { L"Sunday",L"Monday",L"Tuesday",L"Wednesday",L"Thursday",L"Friday",L"Saturday" };
		//static LPCWSTR weekShortString[7]={L"Sun",L"Mon",L"Tues",L"Wed",L"Thur",L"Fri",L"Sat"};
		if (time >= 0 && str.size() == 1)
		{
			bool hasYear, hasMonth, hasDay, hasDayOfWeek, hasHour, hasMinute, hasSecond, hasNS;
			int ymdType;//0为不显示；1为x年x月x日；2为x-x-x；3为x/x/x
			int splitType;//0为不使用分隔；1为空格，2为L'T'
			switch (str[0])
			{
			case L'y':hasYear = hasMonth = true; hasDay = hasDayOfWeek = hasHour = hasMinute = hasSecond = hasNS = false; ymdType = 1; splitType = 0; break;
			case L'm':hasMonth = hasDay = true; hasYear = hasDayOfWeek = hasHour = hasMinute = hasSecond = hasNS = false; ymdType = 1; splitType = 0; break;
			case L'd':hasYear = hasMonth = hasDay = true; hasDayOfWeek = hasHour = hasMinute = hasSecond = hasNS = false; ymdType = 3; splitType = 0; break;
			case L't':hasHour = hasMinute = true; hasYear = hasMonth = hasDay = hasDayOfWeek = hasSecond = hasNS = false; ymdType = 0; splitType = 0; break;
			case L'D':hasYear = hasMonth = hasDay = hasDayOfWeek = true; hasHour = hasMinute = hasSecond = hasNS = false; ymdType = 1; splitType = 0; break;
			case L'T':hasHour = hasMinute = hasSecond = true; hasYear = hasMonth = hasDay = hasDayOfWeek = hasNS = false; ymdType = 0; splitType = 0; break;
			case L's':hasYear = hasMonth = hasDay = hasHour = hasMinute = hasSecond = true; hasDayOfWeek = hasNS = false; ymdType = 2; splitType = 2; break;
			case L'g':hasYear = hasMonth = hasDay = hasHour = hasMinute = true; hasSecond = hasDayOfWeek = hasNS = false; ymdType = 3; splitType = 1; break;
			case L'o':hasYear = hasMonth = hasDay = hasHour = hasMinute = hasSecond = hasNS = true; hasDayOfWeek = false; ymdType = 2; splitType = 2; break;
			case L'u':hasYear = hasMonth = hasDay = hasHour = hasMinute = hasSecond = true; hasDayOfWeek = hasNS = false; ymdType = 2; splitType = 1; break;
			case L'f':hasYear = hasMonth = hasDay = hasHour = hasMinute = true; hasSecond = hasDayOfWeek = hasNS = false; ymdType = 1; splitType = 1; break;
			case L'G':hasYear = hasMonth = hasDay = hasHour = hasMinute = hasSecond = true; hasDayOfWeek = hasNS = false; ymdType = 3; splitType = 1; break;
			case L'F':hasYear = hasMonth = hasDay = hasHour = hasMinute = hasSecond = hasDayOfWeek = true; hasNS = false; ymdType = 1; splitType = 1; break;
			default: return ToString();
			}
			LPWSTR tmpStr = new WCHAR[80];
			LPWSTR p = tmpStr;
			unsigned int days;
			double year = GetYearAndDaysInYear(&days);
			unsigned int month = GetMonthByDaysInYear(year, days);
			if (hasYear)//输出包含年信息
			{
				if (year < 1e16)
					tmpStr += String::WriteUNum((u64)year, tmpStr, 4);
				else
					tmpStr += String::WriteFloatE(year, tmpStr, 52);
				switch (ymdType)
				{
				case 1:*(p++) = L'年'; break;
				case 2:if (hasMonth)*(p++) = L'-'; break;
				case 3:if (hasMonth)*(p++) = L'/'; break;
				}
			}
			if (hasMonth)//输出包含月信息
			{
				if (month >= 10 || ymdType == 2)*(p++) = month / 10 + L'0'; *(p++) = month % 10 + L'0';
				switch (ymdType)
				{
				case 1:*(p++) = L'月'; break;
				case 2:if (hasDay)*(p++) = L'-'; break;
				case 3:if (hasDay)*(p++) = L'/'; break;
				}
			}
			if (hasDay)//输出包含日信息
			{
				if (days >= 10 || hasMonth)*(p++) = days / 10 + L'0';  *(p++) = days % 10 + L'0';
				if (ymdType == 1)
				{
					*(p++) = L'日';
				}
			}
			if (ymdType != 0)switch (splitType)//分隔
			{
			case 1:*(p++) = L' '; break;
			case 2:*(p++) = L'T'; break;
			}
			if (hasHour)//显示小时信息
			{
				days = GetHour();       if (days >= 10)*(p++) = days / 10 + L'0'; *(p++) = days % 10 + L'0'; if (hasMinute)*(p++) = L':';
			}
			if (hasMinute)//显示分信息
			{
				days = GetMinute(); *(p++) = days / 10 + L'0'; *(p++) = days % 10 + L'0'; if (hasSecond)*(p++) = L':';
			}
			if (hasSecond)//显示秒信息
			{
				days = GetSecond(); *(p++) = days / 10 + L'0'; *(p++) = days % 10 + L'0'; if (hasNS)*(p++) = L'.';
			}
			if (hasNS)//显示纳秒信息
			{
				days = (unsigned int)(time*10000000); *(p++) = days / 1000000 + L'0'; *(p++) = (days % 1000000) / 100000 + L'0'; *(p++) = (days % 100000) / 10000 + L'0'; *(p++) = (days % 10000) / 1000 + L'0'; *(p++) = (days % 1000) / 100 + L'0'; *(p++) = (days % 100) / 10 + L'0'; *(p++) = days % 10 + L'0';
			}
			if (hasDayOfWeek)
			{
				*(p++) = L' ';
				size_t len = wcslen(weekString[GetDayOfWeek()]);
				Memory::Copy(p, weekString[GetDayOfWeek()], len*sizeof(wchar_t));
				p += len;
			}
			if (str[0] == L'u')*(p++) = L'Z';
			*p = 0;
			return new String(int(p - tmpStr), tmpStr, NULL);
		}
		return ToString();
	}
#ifdef _CLR //托管支持
	Time::Time(System::DateTime^time)
		:time(GetDays(time->Year, time->Month, time->Day)*EveryDay +
			time->Hour*EveryHour +
			time->Minute*EveryMinute +
			time->Second*EverySecond +
			time->Millisecond*EveryMillisecond)
	{               }
	System::DateTime^Time::ToDateTime()const
	{
		return gcnew System::DateTime(time);
	}
#endif
	ptr<Time>::ptr(const ptr<String>&str) :ptr<ICloneables>(new Time(str)) {}
	/**
	@brief 表示空时间*/
	ptr<Time> const& Time::GetEmptyRef()
	{
		static ptr<Time>*p;
		if (p)return *p;
		Mutex::GetDefaultRef().Lock();
		if (!p)
		{
			static ptr<Time>t = new Time(0);
			t.UseCount.SetEnableThreadSafe(true);
			p = &t;
		}
		Mutex::GetDefaultRef().UnLock();
		return *p;
	}

}
#endif
